<?php
/**
 * Ftp
 *
 * @author haifeng.wu
 */

class Application_Model_Ftp extends Application_Model_Common
{
    /**
     * 配置
     *
     * @var string
     */
    protected $_configs = array('host'=>NULL, 'hostPort'=>'21', 'userName'=>NULL, 'password'=>NULL, 'passive'=>TRUE, 'timeoutTime'=>20, 'logPath'=>NULL);

    /**
     * 连接超时时间(秒)
     *
     * @var integer
     */
    protected $_connId = NULL;

    /**
     * 连接超时时间(秒)
     *
     * @var integer
     */
    protected $_timeoutTime = 10;

    /**
     * Constructor
     *
     * @param array $configs
     * @return void
     */
    public function __construct($configs = array()) {
        if (!empty($configs)) {
            $this->_configs = $configs;
        }
    }

    /**
     * 获取连接ID
     * 
     * @return resource
     */
    public function getConnId() {
        if ($this->_connId === NULL) {
            $this->connect();
        }
        return $this->_connId;
    }
    
    /**
     * 更改当前目录
     * 
     * @param string $dir
     * @return resource
     */
    public function chdir($dir) {
        if ($this->_connId === NULL) {
            $this->connect();
        }
        if (ftp_chdir($this->_connId, $dir)) {
            $errorMessage = date("Y-m-d H:i:s") . ',' . getClientIP() . "\r\n Change directory error!";
            $this->_log($errorMessage);
            throw new Zend_Exception($errorMessage);
        }
    }

    /**
     * 连接
     * 
     * @return void
     */
    public function connect() {
        $this->_connId = @ftp_connect($this->getHost(), $this->getHostPort());
        ftp_set_option($this->_connId, FTP_TIMEOUT_SEC, $this->getTimeoutTime());
        if (!$this->_connId) {
            $errorMessage = date("Y-m-d H:i:s") . ',' . getClientIP() . "\r\nCouldn't connect to {$this->getHost()}:{$this->getHostPort()}!";
            $this->_log($errorMessage);
            throw new Zend_Exception($errorMessage);
        }
        $this->_login();

        if ($this->_configs['passive'] == TRUE) {
            ftp_pasv($this->_connId, TRUE);
        }
    }

    /**
     * 登录
     * 
     * @return void
     */
    private function _login() {
        $connId = $this->getConnId();
        $status = @ftp_login($connId, $this->_configs['userName'], $this->_configs['password']);
        if (!$status) {
            $errorMessage = date("Y-m-d H:i:s") . ',' . getClientIP() . "\r\nLogin error UserName:{$this->_configs['userName']},Password:{$this->_configs['password']}!";
            $this->_log($errorMessage);
        }
    }

    /**
     * 设置host
     * 
     * @param string $host
     * @return void
     */
    public function setHost($host) {
        $this->_configs['host'] = $host;
    }

    /**
     * 获取host
     * 
     * @return string
     */
    public function getHost() {
        return $this->_configs['host'];
    }

    /**
     * 设置host端口
     * 
     * @param string $port
     * @return void
     */
    public function setHostPort($port) {
        $this->_configs['hostPort'] = $port;
    }

    /**
     * 获取host端口
     * 
     * @return string
     */
    public function getHostPort() {
        return $this->_configs['hostPort'];
    }

    /**
     * 设置用户名
     * 
     * @param string $userName
     * @return void
     */
    public function setUserName($userName) {
        $this->_configs['userName'] = $userName;
    }

    /**
     * 获取用户名
     * 
     * @return string
     */
    public function getUserName() {
        return $this->_configs['userName'];
    }

    /**
     * 设置用户密码
     * 
     * @param string $password
     * @return void
     */
    public function setPassword($password) {
        $this->_configs['password'] = $password;
    }

    /**
     * 获取用户密码
     * 
     * @return string
     */
    public function getPassword() {
        return $this->_configs['password'];
    }

    /**
     * 设置是否被动模式
     * 
     * @param string $passive
     * @return void
     */
    public function setPassive($passive) {
        $this->_configs['passive'] = $passive;
    }

    /**
     * 获取是否被动模式
     * 
     * @return string
     */
    public function getPassive() {
        return $this->_configs['passive'];
    }

    /**
     * 设置日志路径
     * 
     * @param string $logPath
     * @return void
     */
    public function setLogPath($logPath) {
        $this->_configs['logPath'] = $logPath;
    }

    /**
     * 获取日志路径
     * 
     * @return string
     */
    public function getLogPath() {
        return $this->_configs['logPath'];
    }

    /**
     * 设置连接超时时间
     *
     * @param string $timeoutTime
     * @return void
     */
    public function setTimeoutTime($timeoutTime) {
        $this->_timeoutTime = $timeoutTime;
    }

    /**
     * 获取连接超时时间
     *
     * @return string
     */
    public function getTimeoutTime() {
        return $this->_timeoutTime;
    }

    /**
     * 下载一个文件
     *
     * @param string $localFilePath
     * @param string $ftpFilePath
     * @param string $mode
     * @return void
     */
    public function download($localFilePath, $ftpFilePath, $mode = 'auto'){
        $connId = $this->getConnId();
        $mode = ($mode == 'ascii') ? FTP_ASCII : FTP_BINARY;
        $result = @ftp_get($connId, $localFilePath, $ftpFilePath, $mode);
        if ($result === FALSE) {
            $errorMessage = date("Y-m-d H:i:s") . ',' . getClientIP() . "\r\nDownload error FTP Path:{$ftpFilePath},Local Path:{$localFilePath},Mode:{$mode}!";
            $this->_log($errorMessage);
            throw new Zend_Exception($errorMessage);
        }
    }

    /**
     * 上传一个文件
     *
     * @param string $localFilePath
     * @param string $ftpFilePath
     * @param string $mode
     * @return void
     */
    public function upload($ftpFilePath, $localFilePath, $mode = 'auto', $permissions = NULL){
        $connId = $this->getConnId();
        $mode = ($mode == 'ascii') ? FTP_ASCII : FTP_BINARY;
        $result = @ftp_put($connId, $ftpFilePath, $localFilePath, $mode);
        if ($result === FALSE) {
            $errorMessage = date("Y-m-d H:i:s") . ',' . getClientIP() . "\r\nUpload error FTP Path:{$ftpFilePath},Local Path:{$localFilePath},Mode:{$mode},permissions:{$permissions}!";
            $this->_log($errorMessage);
            //throw new Zend_Exception($errorMessage);
        }
        if (!empty($permissions)) {
            $this->chmod($ftpFilePath, (int)$permissions);
        }
    }

    /**
     * 创建文件夹
     *
     * @param string $path
     * @param string $permissions
     * @return void
     */
    public function mkdir($path, $permissions = NULL){
        $connId = $this->getConnId();
       $result = @ftp_mkdir($connId, $path);
       if ($result === FALSE) {
          $errorMessage = date("Y-m-d H:i:s") . ',' . getClientIP() . "\r\nMkdir error Path:{$path},permissions:{$permissions}!";
            $this->_log($errorMessage);
           //throw new Zend_Exception($errorMessage);
        }
        if (!empty($permissions)) {
            $this->chmod($path, (int)$permissions);
        }
    }

    /**
     * 重命名
     *
     * @param string $path
     * @param string $newPath
     * @return void
     */
    public function rename($path, $newPath){
        $connId = $this->getConnId();
        $result = @ftp_rename($connId, $path, $newPath);
        if ($result === FALSE) {
            $errorMessage = date("Y-m-d H:i:s") . ',' . getClientIP() . "\r\nRename file error Path:{$path},New Path{$newPath}!";
            $this->_log($errorMessage);
            throw new Zend_Exception($errorMessage);
        }
    }
    

    /**
     * 移动 
     *
     * @access    public
     * @param    string
     * @param    string
     * @return    bool
     */
    public function move($old_file, $new_file)
    {
        return $this->rename($old_file, $new_file);
    }

    /**
     * 删除文件
     *
     * @param string $path
     * @return void
     */
    public function deleteFile($path){
        $connId = $this->getConnId();
        $result = @ftp_delete($connId, $path);
        if ($result === FALSE) {
            $errorMessage = date("Y-m-d H:i:s") . ',' . getClientIP() . "\r\nDelete file error Path:{$path}!";
            $this->_log($errorMessage);
            //throw new Zend_Exception($errorMessage);
        }
    }

    /**
     * 删除文件夹
     *
     * @param string $path
     * @return void
     */
    public function deleteDirectory($path){
        $connId = $this->getConnId();
        $listFiles = $this->listFiles($path);
        if ($listFiles !== FALSE && count($listFiles) > 0) {
            foreach ($listFiles as $item) {
                if ( ! @ftp_delete($connId, $item)) {
                    $this->deleteDirectory($item);
                }
            }
        }

        $result = @ftp_rmdir($connId, $path);
        if ($result === FALSE) {
            $errorMessage = date("Y-m-d H:i:s") . ',' . getClientIP() . "\r\nDelete path error Path:{$path}!";
            $this->_log($errorMessage);
            throw new Zend_Exception($errorMessage);
        }
    }

    /**
     * 更改权限
     *
     * @param string $path
     * @param string $permissions
     * @return void
     */
    public function chmod($path, $permissions){
        $connId = $this->getConnId();
        $result = @ftp_chmod($connId, $permissions, $path);
        if ($result === FALSE) {
            $errorMessage = date("Y-m-d H:i:s") . ',' . getClientIP() . "\r\nChmod unable Path:{$path}!";
            $this->_log($errorMessage);
            throw new Zend_Exception($errorMessage);
        }
    }

    /**
     * 列表
     *
     * @param string $path
     * @return array
     */
    public function listFiles($path){
        $connId = $this->getConnId();
        
        return ftp_nlist($connId, $path);
    }

    /**
     * 记录日志
     *
     * @param string $log
     * @return void
     */
    private function _log($log){
        $time = time();
        $apiLogPath = "{$this->_configs['logPath']}/" . date("Y", $time);
        createDirectory($apiLogPath);
        $fopen = fopen($apiLogPath . "/". date('m-d', $time) . ".log", 'a');
        fwrite($fopen, $log . "\r\n\r\n");
        fclose($fopen);
    }

    /**
     * 关闭
     *
     * @return array
     */
    public function close(){
        if ($this->_connId !== NULL) {
            @ftp_close($this->_connId);
            $this->_connId = NULL;
        }
    }

    /**
     * destructor
     *
     * @return void
     */
    public function __destruct(){
        $this->close();
    }
}